package com.jy.datapipeline.common.util;

import io.micrometer.core.instrument.util.StringUtils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;


/**
 * 日期操作类
 * @author tmc.sun
 */
public class DateUtils {
	
	public static final String DATE_FORMAT = "yyyy-MM-dd";
	public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 将日期转换为指定格式的日期字符串
	 * @author tmc.sun
	 * @param date 日期
	 * @param format 格式化模型,如："yyyy-MM-dd HH:mm:ss"
	 * @return 格式化后的日期字符串
	 */
	public static String formatDate(Date date, String format) {
		if (date == null){
			return "";
		}
		
		DateFormat df = new SimpleDateFormat(format);
		String dateString = df.format(date);
		return dateString;
	}
	public static String getNow(){
		String now=DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss");
		return now;
	}
	/**
	 * 将日期字符串转换成指定格式的日期
	 * @author tmc.sun
	 * @param dateString 日期字符串
	 * @param format 格式化模型,如："yyyy-MM-dd HH:mm:ss"
	 * @return date 指定格式的日期
	 */
	public static Date parseDate(String dateString, String format) {
		Date date = null;

		if (dateString!=null){
			try {
				DateFormat df = new SimpleDateFormat(format);
				date = df.parse(dateString);
			} catch (ParseException e) {
				e.printStackTrace();
				return null;
			}
		}
		return date;
	}
	public static Date transferDateFormat(String oldDateStr) {
		if (StringUtils.isBlank(oldDateStr)){
			return null;
		}
		Date date = null;
		Date date1 = null;
		String dateStr = null;
		try {
			System.out.println(oldDateStr);
			dateStr = oldDateStr.replace("T", " ").replace("Z","");
			//dateStr = oldDateStr.replace("Z", " CST");//是空格+UTC
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			System.out.println(df);
			date1 = df.parse(dateStr);
//			SimpleDateFormat df1 = new SimpleDateFormat ("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
//			date = df1.parse(date1.toString());
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar ca=Calendar.getInstance();
		ca.setTime(date1);
		ca.set(Calendar.HOUR,+8);
		return ca.getTime();
	}
	public static Date transferDateFormat2(String oldDateStr) {
		//字符串时间，带T带Z带毫秒值
		//String stime = "2020-11-18T04:31:40.886Z";
		//创建对应的pattern，注意T和Z两个字符使用单引号引起来，毫秒值使用大写S表示
		DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
		//字符串时间转换成时间类型
		LocalDateTime date = LocalDateTime.parse(oldDateStr, pattern);
		//时间类型转时间戳类型

		//long ts = date.toInstant(ZoneOffset.of("+8")).toEpochMilli();
		//LocalTime ts=date.now().minusHours(8).toLocalTime();
		Date newDate=Date.from(date.toInstant(ZoneOffset.of("+8")));
		long times=newDate.getTime()+(1000*60*60*8);
			return  new Date(times);
	}
//	public static void main(String[] args) {
//		Date d=DateUtils.transferDateFormat("2021-05-26T16:00:00.000Z");
//		System.out.print(d);
//	}
	/**
	 * 获取当前时间
	 * @author tmc.sun
	 * @return 当前时间
	 */
	public static Date getNowTime() {
		return new Date();
	}

	/**
	 * 获取指定日期所在月份的月初
	 * @author tmc.sun
	 * @param date 当前时间
	 * @return 指定日期所在月份的月初
	 */
	public static Date getFirstDay(Date date) {
		if (date != null){
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.set(5, 1);
			cal.set(11, 0);
			cal.set(12, 0);
			cal.set(13, 0);
			cal.set(14, 0);
			return cal.getTime();
		}
		return null;
	}
	
	/**
	 * 获取指定日期前一天的日期
	 * @author tmc.sun
	 * @param date 日期参数
	 * @return 指定日期前一天的日期
	 */
	public static Date getLastDay(Date date) {
		if (date != null){
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(2, 1);
			cal.add(5, -1);
			cal.set(11, 23);
			cal.set(12, 59);
			cal.set(13, 59);
			cal.set(14, 999);
			return cal.getTime();
		}
		return null;
	}
	
	/**
	 * 根据日期获取 Calendar实例
	 * @author tmc.sun
	 * @param date 日期参数
	 * @return calendar Calendar实例
	 */
	public static Calendar getCalendar(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}

	/**
	 * 获取指定日期所在月份的最大天数
	 * @author tmc.sun
	 * @param date 日期参数
	 * @return 日期所在月份的最大天数
	 */
	public static int getDaysInMonth(Date date) {
		if (date == null){
			return 0;
		}
		
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.getActualMaximum(5);
	}

	/**
	 * 获取指定日期的月份加  1 后的日期
	 * @author tmc.sun
	 * @paramdate日期参数
	 * @return 日期的月份加  1 后的日期
	 */
	public static Date getNexMonthDate(Date d) {
		return addMonth(d, 1);
	}

	/**
	 * 将日期的月份加 指定的数值
	 * @author tmc.sun
	 * @param date 日期
	 * @param monthNumber 数值,如加一个月,则是 1
	 * @return 日期的月份加指定的数值后的日期
	 */
	public static Date addMonth(Date date, int monthNumber) {
		if (date == null){
			return date;
		}
		Calendar cal = Calendar.getInstance();
		cal.clear();
		cal.setTime(date);
		cal.add(2, monthNumber);
		return cal.getTime();
	}

	/**
	 * 获取指定日期的月份减  1 后的日期
	 * @author tmc.sun
	 * @paramdate日期参数
	 * @return 日期的月份加减 1 后的日期
	 */
	public static Date getPreviousMonth(Date d) {
		return addMonth(d, -1);
	}

	/**
	 * 获取指定年份所有月份的第一天的日期
	 * @author tmc.sun
	 * @param year 年份
	 * @return dates 指定年份所有月份的第一天的日期
	 */
	public static Date[] getYearMonthList(int year) {
		Calendar cal = Calendar.getInstance();
		
		if (year > 0){
			cal.set(1, year);
		}
		
		cal.set(5, 1);
		cal.set(11, 0);
		cal.set(12, 0);
		cal.set(13, 0);
		cal.set(14, 0);

		Date[] dates = new Date[12];
		
		for (int i = 0; i < 12; i++) {
			Calendar c = (Calendar) cal.clone();
			c.set(2, i);
			dates[i] = c.getTime();
		}
		return dates;
	}

	/**
	 * 获取指定年月的月份中工作日的天数(即:该月非周六周日的天数)
	 * @author tmc.sun
	 * @param year 年份
	 * @param month 月份
	 * @return 工作日的天数(即:该月非周六周日的天数)
	 */
	public static int getWorkingDay(String year, String month) {
		Calendar cal_start = Calendar.getInstance();
		cal_start.set(1, Integer.parseInt(year));
		cal_start.set(2, Integer.parseInt(month) - 1);
		cal_start.set(5, 1);

		Calendar cal_end = Calendar.getInstance();
		cal_end.set(1, Integer.parseInt(year));
		cal_end.set(2, Integer.parseInt(month) - 1);

		int monthdays = cal_end.getActualMaximum(5);
		cal_end.set(5, monthdays);

		return getWorkingDay(cal_start, cal_end);
	}
	
	/**
	 * 获取两个日期间相差的天数
	 * @author tmc.sun
	 * @param calendar1 日期1
	 * @param calendar2 日期2
	 * @return 两个日期间相差的天数
	 */
	public static int getDaysBetween(Calendar calendar1, Calendar calendar2) {
		if (calendar1.after(calendar2)) {
			Calendar calendar = calendar1;
			calendar1 = calendar2;
			calendar2 = calendar;
		}
		
		int days = calendar2.get(6) - calendar1.get(6) + 1;
		int y2 = calendar2.get(1);
		
		if (calendar1.get(1) != y2) {
			calendar1 = (Calendar) calendar1.clone();
			do {
				days += calendar1.getActualMaximum(6);
				calendar1.add(1, 1);
			} while (calendar1.get(1) != y2);
		}
		return days;
	}

	/**
	 * 获取两个日期间的工作日的天数(即:非周六周日的天数)
	 * @author tmc.sun
	 * @param calendar1   日期1
	 * @param calendar2   日期2
	 * @return result 两个日期间的工作日的天数(即:非周六周日的天数)
	 */
	public static int getWorkingDay(Calendar calendar1, Calendar calendar2) {
		int result = 0;
		int betweendays = getDaysBetween(calendar1, calendar2);
		int firstDayInWeek = calendar1.get(7);

		if (firstDayInWeek > 1) {
			result = 7 - firstDayInWeek;
			betweendays -= result + 1;
		}
		
		result += betweendays / 7 * 5;
		int days = betweendays % 7;
		
		if (days > 0) {
			result += days - 1;
		}
		return result;
	}
	
	/**
	 * 判断指定年份是否是闰年
	 * @author tmc.sun
	 * @param year 年份
	 * @return result true表示是闰年,false表示不是
	 */
	public static boolean checkLeapYear(int year) {
		boolean result = false;
		
		if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){
			result = true;
		}
		return result;
	}
	
	/**
	 * 判断指定日期所在月份的最大天数
	 * @author tmc.sun
	 * @param date 日期
	 * @return maxDay 日期所在月份的最大天数
	 */
	public static int getMaxDay(Date date){
		int maxDay = 0;
		
		if(date != null){
			Calendar calendar = DateUtils.getCalendar(date);
			maxDay = calendar.getActualMaximum(Calendar.DATE);
		}
		return maxDay;
	}
	
	/*public static void main(String[] args) {
		String dateString = "2011-02-08";
		Date date = DateUtils.parseDate(dateString, "yyyy-MM-dd");
		System.out.println("**************:" + DateUtils.getMaxDay(date));
		getWeekEndDate();
	}*/
	
	
	//获取当前月第一天：
	public static String getMonthOfFistDay(){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Calendar c = Calendar.getInstance();    
		c.add(Calendar.MONTH, 0);
		c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
		String first = format.format(c.getTime());
		return first;
	}
	
	//获取当前月最后一天
	public static String getMonthOfLastDay(){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Calendar ca = Calendar.getInstance();    
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));  
		String last = format.format(ca.getTime());
		return last;
	}
	
	/*
	 *获取本周第一天 
	 * */
	
	public static String getWeekStartDate(){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Calendar ca = Calendar.getInstance();
		ca.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); 
		ca.set(Calendar.HOUR_OF_DAY, 0);
		ca.set(Calendar.MINUTE, 0);
		ca.set(Calendar.SECOND, 0);
		String weekStartDate = format.format(ca.getTime());
		return weekStartDate;
	}
	
	
	/*
	 * 获取本周最后一天
	 * */
	
	public static String getWeekEndDate(){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date=new Date();
		Calendar ca = new GregorianCalendar();
		ca.setFirstDayOfWeek(Calendar.MONDAY);
		ca.setTime(date);
		ca.set(Calendar.DAY_OF_WEEK, ca.getFirstDayOfWeek() + 6); // Sunday
        
        String weekEndDate = format.format(ca.getTime());
		return weekEndDate;
	}
	
	
	/** 
     * 获取某年某月的第一天 
     * @Title:getFisrtDayOfMonth 
     * @Description: 
     * @param:@param year 
     * @param:@param month 
     * @param:@return 
     * @return:String 
     * @throws 
     */  
    public static String getFisrtDayOfMonth(int year,int month)  {  
        Calendar cal = Calendar.getInstance();  
        //设置年份  
        cal.set(Calendar.YEAR,year);  
        //设置月份  
        cal.set(Calendar.MONTH, month-1);  
        //获取某月最小天数  
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);  
        //设置日历中月份的最小天数  
        cal.set(Calendar.DAY_OF_MONTH, firstDay);  
        //格式化日期  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
        String firstDayOfMonth = sdf.format(cal.getTime());  
          
        return firstDayOfMonth;  
    }
    
    /**
     * 获取某月的最后一天
     * @Title:getLastDayOfMonth
     * @Description:
     * @param:@param year
     * @param:@param month
     * @param:@return
     * @return:String
     * @throws
     */
    public static String getLastDayOfMonth(int year,int month){
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR,year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());
         
        return lastDayOfMonth;
    }
    
    
    /*
     * 获得指定年指定月的天数
     * */
    public static int getDaysOfMonth(int year,int month){
    	Calendar time=Calendar.getInstance(); 
    	time.clear(); 
    	time.set(Calendar.YEAR,year); 
    	//year年
    	time.set(Calendar.MONTH,month-1);
    	//Calendar对象默认一月为0,month月            
    	int days=time.getActualMaximum(Calendar.DAY_OF_MONTH);//本月份的天数
    	
    	return days;
    }
    
    //获取当前时间前一天的日期
    public static Date addDay(Date dateNow,int day){
    	Calendar calendar = Calendar.getInstance(); //得到日历
    	calendar.setTime(dateNow);//把当前时间赋给日历
    	calendar.add(Calendar.DAY_OF_MONTH, day);
    	return calendar.getTime();
    }

	//获取当前时间前几分钟的日期
	public static Date addHour(Date dateNow,int hours){
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.setTime(dateNow);//把当前时间赋给日历
		calendar.add(Calendar.HOUR_OF_DAY, hours);
		return calendar.getTime();
	}

	//获取当前时间前几分钟的日期
	public static Date addMinute(Date dateNow,int minutes){
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.setTime(dateNow);//把当前时间赋给日历
		calendar.add(Calendar.MINUTE, minutes);
		return calendar.getTime();
	}

    /**
	 * @see获得指定两个日期之间的全部日期()
	 * @return String 
	 * @throws ParseException 
	 */ 
    public static List<String> getBetweenStartEndDate(String startDate,String EndDate) throws ParseException{
	 	SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd");
		Date beginDate=sim.parse(startDate);
		Date endDate=sim.parse(EndDate);
		
		List<String> dateArray = new ArrayList<String>();
		dateArray.add(startDate);//把开始时间加入集合
	    Calendar cal = Calendar.getInstance();
	    //使用给定的 Date 设置此 Calendar 的时间
	    cal.setTime(beginDate);
	    boolean bContinue = true;
	    while (bContinue) {
	        //根据日历的规则，为给定的日历字段添加或减去指定的时间量
	        cal.add(Calendar.DAY_OF_MONTH, 1);
	        // 测试此日期是否在指定日期之后
	        if (endDate.after(cal.getTime())) {
	        	dateArray.add(sim.format(cal.getTime()));
	        } else {
	            break;
	        }
	    }
	    dateArray.add(EndDate);//把结束时间加入集合
	    return dateArray;
 }
    
    /***************************************** 
	* @功能     计算某年某周的开始日期 
	* @return  interger 
	* @throws ParseException 
	****************************************/  
	public static String getYearWeekFirstDay(int yearNum,int weekNum) throws ParseException {  
	  
	    Calendar cal = Calendar.getInstance();  
	    cal.set(Calendar.YEAR, yearNum);  
	    cal.set(Calendar.WEEK_OF_YEAR, weekNum);  
	    cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);  
	    //分别取得当前日期的年、月、日  
	    String tempYear = Integer.toString(cal.get(Calendar.YEAR));  
	    String tempMonth = Integer.toString(cal.get(Calendar.MONTH) + 1);  
	    String tempDay = Integer.toString(cal.get(Calendar.DATE));  
	    String tempDate = tempYear + "-" +tempMonth + "-" + tempDay;  
	    return SetDateFormat(tempDate,"yyyy-MM-dd");  
	}
	
	/***************************************** 
	* @功能     计算某年某周的结束日期 
	* @return  interger 
	* @throws ParseException 
	****************************************/  
	public static String getYearWeekEndDay(int yearNum,int weekNum) throws ParseException {  
	    Calendar cal = Calendar.getInstance();  
	    cal.set(Calendar.YEAR, yearNum);  
	    cal.set(Calendar.WEEK_OF_YEAR, weekNum + 1);  
	    cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);  
	    //分别取得当前日期的年、月、日  
	    String tempYear = Integer.toString(yearNum);  
	    String tempMonth = Integer.toString(cal.get(Calendar.MONTH) + 1);  
	    String tempDay = Integer.toString(cal.get(Calendar.DATE));  
	    String tempDate = tempYear + "-" +tempMonth + "-" + tempDay;  
	    return SetDateFormat(tempDate,"yyyy-MM-dd");  
	}
	
	/** 
	 * @see取得指定时间的给定格式()
	 * @return String 
	 * @throws ParseException 
	 */  
	 public static String SetDateFormat(String myDate,String strFormat) throws ParseException {  

	       SimpleDateFormat sdf = new SimpleDateFormat(strFormat);  
	       String sDate = sdf.format(sdf.parse(myDate));  
	       System.err.println(sDate);  
	       return sDate;  
	 }

	/**
	 * 第一种方式，指定时区偏移量，并且时间字符串包含时区偏移量的具体值，例如+07:00
	 * yyyy-MM-dd'T'HH:mm:ss.SSS+07:00
	 * @param dateStr
	 * @return
	 * @throws Exception
	 */
	public static Date strToDate(String dateStr) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+08:00");
		Date date = sdf.parse(dateStr);
		System.out.println(date);
		return date;
	}
	public static void main(String[] args) throws Exception {
		//String startTimeStr="2021-10-22T22:00:00.000+08:00";
		//Date startTime= DateUtils.strToDate(startTimeStr);
		String time="2022-01-19T05:49:43.163Z";
		Date date= DateUtils.transferDateFormat2(time);


		System.out.println(DateUtils.formatDate(date,"yyyy-MM-dd HH:mm:ss"));
	}
	 
	 
}
